package fiuba.algo3.gpschallenge.modelo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import fiuba.algo3.gpschallenge.modelo.dificultad.Dificultad;
import fiuba.algo3.gpschallenge.persistencia.PersistenciaJugador;
import fiuba.algo3.gpschallenge.persistencia.PersistenciaMapa;
import fiuba.algo3.gpschallenge.persistencia.PersistenciaPuntaje;

public class Juego {

	private Jugador jugador;
	private Dificultad dificultad;
	private Puntaje puntosDeJugador;
	private Ranking ranking;
	private Mapa mapa;
	private PersistenciaMapa persistenciaMapa;
	private PersistenciaJugador persistenciaJugador;
	private PersistenciaPuntaje persistenciaPuntos;


	public Juego(){
		persistenciaMapa = new PersistenciaMapa();
		persistenciaJugador = new PersistenciaJugador();
		persistenciaPuntos = new PersistenciaPuntaje();
	}


	public void inicializarJuego(){
		juegoNuevo();
		
	}
	
	public void guardarPartida() throws JAXBException{
		persistenciaJugador.persistirJugador(jugador);
		persistenciaMapa.persistirMapa(mapa, jugador.getNombre());
		persistenciaPuntos.persistirPuntos(puntosDeJugador);
	}

	private void juegoNuevo(){
		jugadorNuevo();
		if (puntosDeJugador == null)
			setpuntosDeJugador(new Puntaje());
		cargarMapadexml();
		cargarRanking();
		jugador.posicionar(0, 0);
		jugador.getPosicionActual().establecerLimites(mapa);

	}

	private void cargarMapadexml(){
		try {
			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			String rutaXML = "./Mapas/MapaN1.xml";
			File file = new File(rutaXML);
			Document doc = docBuilder.parse(file);

			this.mapa = new Mapa(doc);

		} 
		catch (ParserConfigurationException | SAXException | IOException e) {
			e.printStackTrace();
		}
	}

	public void jugadorNuevo(){				
		jugador = new Jugador();
	}
	
	
	public void cargarjuego(String nombreJugador) {
		cargarjugador(nombreJugador);
		cargarmapa(jugador.getNombre());
		cargarpuntos();
		this.dificultad=puntosDeJugador.getDificultad();
	}
	
	public void inicializarJugadorViejo(){
		cargarpuntos();
		this.dificultad=puntosDeJugador.getDificultad();
	}

	private void cargarpuntos(){
		String nombrexmlpuntos=jugador.getNombre()+"-puntos";
		String rutaxmlpuntos =persistenciaPuntos.generarRutaArchivoXML(jugador.getNombre(), nombrexmlpuntos) ;

		try {
			setpuntosDeJugador(persistenciaPuntos.cargarPuntos(rutaxmlpuntos));
		} catch (FileNotFoundException | JAXBException e) {
			e.printStackTrace();
		}
	}

	private void cargarmapa(String nombrejugador){
		try {
			setMapa(persistenciaMapa.cargarMapa(nombrejugador));
		} catch (ClassNotFoundException | IOException e) {
			e.printStackTrace();
		}
	}

	private void cargarjugador(String nombreJugador){
		String nombreArchivojugador=nombreJugador+"-jugador";
		String rutaxmljugador =persistenciaJugador.generarRutaArchivoXML(nombreJugador, nombreArchivojugador) ;
		try {
			jugador = persistenciaJugador.cargarjugador(rutaxmljugador);
		} catch (FileNotFoundException | JAXBException e) {
			e.printStackTrace();
		}
	}

	public void cargarRanking(){		// Lo seteo public, porque cargo el ranking desde el panel Elegir Jugador. 
		String nombrexml="RANKING";		// Solo necesito cargar el ranking
		String rutaxml =persistenciaPuntos.generarRutaArchivoXML("JUEGO", nombrexml) ;
		try {
			setRanking(persistenciaPuntos.cargarRanking(rutaxml));
		} catch (FileNotFoundException e) {
			setRanking(new Ranking());
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}

public void terminarJuego(){	
	this.puntosDeJugador.setPuntaje(this.jugador);		
	this.ranking.addPuntaje(this.puntosDeJugador);
	this.ranking.ordenar();					
		
		try {
			persistenciaPuntos.persistirRanking(ranking);
			persistenciaPuntos.persistirPuntos(puntosDeJugador);
		} catch (JAXBException e) {
			
			e.printStackTrace();
		}
		
	}
	

	public Jugador getJugador(){
		return jugador;
	}

	public void setNombreJugador(String nombreJugadorIngresado){
		this.jugador.setNombre(nombreJugadorIngresado);
	}
	

	public Puntaje getpuntosDeJugador() {
		return puntosDeJugador;
	}
	
	
	private void setpuntosDeJugador(Puntaje puntosDeJugador) {
		this.puntosDeJugador = puntosDeJugador;
	}
	
	public Ranking getRanking() {
		return ranking;
	}
	
	private void setRanking(Ranking ranking) {
		this.ranking = ranking;
	}
	
	public Dificultad getDificultad(){
		return dificultad;
	}
	
	public void setDificultad(Dificultad dificultad){
		this.dificultad = dificultad;
	}
	
	public PersistenciaJugador getPersistenciaJugador(){
		return persistenciaJugador;
	}
	
	public Mapa getMapa() {
		return mapa;
	}
	
	private void setMapa(Mapa mapa) {
		this.mapa = mapa;
	}

	public void setPuntosDeJugador(Puntaje puntajeJugador){
		this.puntosDeJugador = puntajeJugador;
	}

	public void resetJugador(String nombreJugador) {
		this.puntosDeJugador=new Puntaje(nombreJugador,dificultad);
	}
	
	public void resetearJuego(){
		String nombreJugador = getJugador().getNombre();
		Dificultad dificultadDeJuego = getDificultad();
		inicializarJuego();
		getJugador().setNombre(nombreJugador);
		getpuntosDeJugador().setNombreJugador(nombreJugador);
		setDificultad(dificultadDeJuego);
		getpuntosDeJugador().setDificultad(dificultadDeJuego);
	}

}
